/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yoga.algo.process;

import yoga.algo.phenotype.Individual;
import yoga.algo.phenotype.PopulationStatistics;
import yoga.probability.Probablistics;

public class RouletteSelection<T> implements ISelectionMethod<T>
{
    public RouletteSelection()
    {
    }

    @Override
    public Individual<T> getSelectedIndividual(PopulationStatistics<T> populationStatistics)
    {
        double accumulatedFitValues = populationStatistics.getNuetralOrZeroValue();
        double totalSumOfFitValues = populationStatistics.getSumFitnessValue();

        Individual<T> selectedIndividual = null;

        double slot = Probablistics.getRandomFloatWithinRange(0, 1);

        for (Individual<T> currentIndividual : populationStatistics)
        {
            double currentFitValueBySum = populationStatistics.getFitnessValue(currentIndividual) / totalSumOfFitValues;
            double previousAccumulatedFitValues = accumulatedFitValues;
            accumulatedFitValues += currentFitValueBySum;
            //Note ! - if construct holdes a unary operator ++ for checking if currentFitValue is within range of accumulated sums
            //0 0.1 0.15    0.3 0.5 0.7 0.9 0.95 0.98
            //f.e: random slot chosen is 0.6, check if it is within rane of current individual 0.5 - 0.7 (indivudal holdes 20% of sum fit value).
            if ((slot >= previousAccumulatedFitValues) && (slot <= accumulatedFitValues))
            {
                selectedIndividual = currentIndividual;
                break;
            }
        }

        return selectedIndividual;
    }
//    @Override
//    public Individual<T> getSelectedIndividual(PopulationStatistics<T> populationStatistics)
//    {
//        ArrayList<Individual<T>> roulette = new ArrayList<Individual<T>>();
//        for (Individual<T> currentIndividual : populationStatistics)
//        {
//            IFitnessValue<T> fitnessValue = populationStatistics.getFitnessValuDevidedBySumFitness(currentIndividual);
//            int numberOfSlots = fitnessValue.multiplyByInt(s_rouletteSize);
//            while (numberOfSlots >= 0)
//            {
//                roulette.add(currentIndividual);
//                numberOfSlots--;
//            }
//            
//            if (roulette.size() >= s_rouletteSize)
//            {
//                break;
//            }
//        }
//
//        int index = Probablistics.getRandomInt(roulette.size());        
//        Individual<T> selectedIndividual = roulette.get(index);
//
//        return selectedIndividual;
//    }
}
